﻿/*
Nombre:                         BancoDao
Descripcion:                    Implementacion que maneja las funciones principales sobre el catalogo de bancos manejado en la capa de persistencia 
Dependencias:                 
Fecha de creación:              20080905
Autor:                          VMORALES
Fecha de modifcación:         
Responsable:                  
Num. de modifcación:            0
*/

#region Imports

using Electrocucaracha.AdminPersonal.DAO.Entidades;
using Electrocucaracha.AdminPersonal.DAO.Acciones;
using Common.Logging;
using System;

#endregion

namespace Electrocucaracha.AdminPersonal.DAO
{
    /// <summary>
    /// Implementacion que maneja las funciones principales sobre el catalogo de bancos manejado en la capa de persistencia
    /// </summary>
    public class BancoDao : BaseDao, IBancoDao
    {
        #region Constantes

        #endregion

        #region Miembros

        private static readonly ILog log = LogManager.GetLogger(typeof(BancoDao));
        private static BancoDao instancia = new BancoDao();

        #endregion

        #region Propiedades

        /// <summary>
        /// Obtiene la instancia unica para el catalogo de bancos
        /// </summary>
        public static BancoDao Instancia
        {
            get
            {
                log.Info("Inicio BancoDao.Instancia.get");

                if (instancia == null)
                {
                    instancia = new BancoDao();
                }

                log.Info("Fin BancoDao.Instancia.get");

                return instancia;
            }
        }//Instancia

        #endregion

        #region Constructores

        private BancoDao()
            : base()
        {
            log.Info("Inicio BancoDao.ctor()");

            log.Info("Fin BancoDao.ctor()");
        }//BancoDao

        #endregion

        #region Funciones

        /// <summary>
        /// Funcion que valida si existe un banco en la capa de persistencia que tenga la misma descripcion
        /// </summary>
        /// <param name="descripcion">Cadena a buscar en la base de datos</param>
        /// <returns>Verdadero en caso de que no exista ningun banco</returns>
        private bool Existe(string descripcion)
        {
            log.Info("Inicio BancoDao.Existe(string descripcion)");

            log.Debug("Descripcion a buscar : " + descripcion);
            bool respuesta = this.ObtenerPorDescripcion(descripcion) != null;
            log.Debug("Existe banco por descripcion : " + respuesta);

            log.Info("Fin BancoDao.Existe(string descripcion)");

            return respuesta;
        }//Existe

        #endregion

        #region IGenericoDao

        /// <summary>
        /// Funcion que agrega un objeto de tipo banco a la capa de persistencia
        /// </summary>
        /// <param name="banco">Objeto a ser agregado a la capa de persistencia</param>
        /// <returns>Verdadero en caso de exito en la insercion del objeto falso en caso contrario</returns>
        public bool Agregar(ref BancoDTO banco)
        {
            log.Info("Inicio BancoDao.Agregar(ref BancoDTO banco)");

            //Validacion de parametros
            Validar(banco, Validaciones.Nulo | Validaciones.DescripcionVacia);

            Accion accion = admin.ObtenerAccion(CatalogoAcciones.Banco.AGREGAR);
            log.Debug("Accion : " + accion);
            accion.Parametros[Accion.INPUT] = banco;
            accion.Parametros[Accion.OUTPUT] = false;

            //Se compara solo su descripcion ya que el identificador carece de importancia
            if (!this.Existe(banco.Descripcion))
            {
                log.Info("Insercion del banco");
                admin.Ejecutar(accion);
            }

            log.Info("Fin BancoDao.Agregar(ref BancoDTO banco)");

            return (bool)accion.Parametros[Accion.OUTPUT];
        }//Agregar

        /// <summary>
        /// Funcion que agrega un conjunto de objetos de tipo banco a la capa de persistencia
        /// </summary>
        /// <param name="bancos">Conjunto de objetos de tipo banco a ser agregados</param>
        /// <returns>El indice del ultimo banco el cual fue agregado con exito a la capa de persistencia</returns>
        public int Agregar(ref BancoDTO[] bancos)
        {
            log.Info("Inicio BancoDao.Agregar(ref Banco[] bancos)");

            //Validacion de datos
            Validar(bancos, Validaciones.Nulo & Validaciones.DescripcionVacia);

            int i = 0;
            for (;i < bancos.Length; i++)
            {
                if (!Agregar(ref bancos[i]))
                {
                    log.Error("No se pudo agregar el banco con la descripcion : " + bancos[i].Descripcion);
                    break;
                }
            }

            log.Info("Fin BancoDao.Agregar(ref Banco[] bancos)");

            return i;
        }//Agregar

        /// <summary>
        /// Funcion que elimina(en caso de existir) un objeto de tipo banco de la capa de persistencia
        /// </summary>
        /// <param name="banco">Objeto a ser eliminado</param>
        /// <returns>Verdadero en caso de eliminacion falso en caso contrario</returns>
        public bool Eliminar(BancoDTO banco)
        {
            log.Info("Inicio BancoDao.Eliminar(BancoDTO banco)");

            //Validacion de parametros
            if (!Existe(banco))
            {
                log.Error("No existe el banco a eliminar");
                throw new DAOException("No existe el banco a eliminar");
            }

            Accion accion = admin.ObtenerAccion(CatalogoAcciones.Banco.ELIMINAR);
            log.Debug("Accion : " + accion);
            accion.Parametros[Accion.INPUT] = banco;
            admin.Ejecutar(accion);

            log.Info("Fin BancoDao.Eliminar(BancoDTO banco)");

            return (bool)accion.Parametros[Accion.OUTPUT];
        }//Eliminar

        /// <summary>
        /// Funcion que elimina(en caso de existir) un conjunto de objetos de tipo banco de la capa de persistencia
        /// </summary>
        /// <param name="bancos">Conjunto de objetos a ser eliminados</param>
        /// <returns>El indice del ultimo banco el cual fue eliminado con exito de la capa de persistencia</returns>
        public int Eliminar(BancoDTO[] bancos)
        {
            log.Info("Inicio BancoDao.Eliminar(Banco[] bancos)");

            int i = 0;
            for (; i < bancos.Length; i++)
            {
                if (!Eliminar(bancos[i]))
                {
                    log.Error("No se pudo eliminar el banco con la descripcion : " + bancos[i].Descripcion);
                    break;
                }
            }

            log.Info("Fin BancoDao.Eliminar(Banco[] bancos)");

            return i;
        }//Eliminar

        /// <summary>
        /// Funcion que obtiene un banco, de la capa de persistencia, a partir de su identificador
        /// </summary>
        /// <param name="id">Identificador del banco a obtener</param>
        /// <returns>Un objeto de tipo banco en caso de encontrarlo nulo en caso contrario</returns>
        public BancoDTO Obtener(int id)
        {
            log.Info("Inicio BancoDao.Obtener(int id)");

            //Validacion de parametros
            if (id < -1)
            {
                log.Error("No existen bancos con identificadores negativos");
                throw new DAOException("No existen bancos con identificadores negativos");
            }

            BancoDTO resultado = null;
            Accion accion = admin.ObtenerAccion(CatalogoAcciones.Banco.OBTENER);
            accion.Parametros[Accion.INPUT] = id;
            log.Debug("Accion : " + accion);
            admin.Ejecutar(accion);
            resultado = accion.Parametros[Accion.OUTPUT] as BancoDTO;

            log.Info("Fin BancoDao.Obtener(int id)");

            return resultado;
        }//Obtener

        /// <summary>
        /// Funcion que devuelve todos los bancos registrados en la capa de persistencia
        /// </summary>
        /// <returns>Conjunto de bancos</returns>
        public BancoDTO[] Obtener()
        {
            log.Info("Inicio BancoDao.Obtener()");

            BancoDTO[] resultado = null;
            Accion accion = admin.ObtenerAccion(CatalogoAcciones.Banco.OBTENER_TODOS);
            log.Debug("Accion : " + accion);
            admin.Ejecutar(accion);
            resultado = accion.Parametros[Accion.OUTPUT] as BancoDTO[];

            if (resultado != null && resultado.Length == 0)
            {
                log.Warn("Reseteando el valor obtenido");
                resultado = null;
            }

            log.Info("Fin BancoDao.Obtener()");

            return resultado;
        }//Obtener

        /// <summary>
        /// Funcion que actualiza en la capa de persistencia el objeto solicitado
        /// </summary>
        /// <param name="banco">Objeto a ser actualizado en la capa de persistencia</param>
        /// <returns>Verdadero en caso de exito falso en caso contrario</returns>
        public bool Actualizar(BancoDTO banco)
        {
            log.Info("Inicio BancoDao.Actualizar(BancoDTO banco)");

            //Validacion de parametros
            Validar(banco, Validaciones.Nulo | Validaciones.IdentificadorNegativo);
            if (!Existe(banco))
            {
                log.Error("No existe el banco a actualizar");
                throw new DAOException("No existe el banco a actualizar");
            }

            Accion accion = admin.ObtenerAccion(CatalogoAcciones.Banco.ACTUALIZAR);
            log.Debug("Accion : " + accion);
            accion.Parametros[Accion.INPUT] = banco;
            admin.Ejecutar(accion);

            log.Info("Fin BancoDao.Actualizar(BancoDTO banco)");

            return (bool)accion.Parametros[Accion.OUTPUT];
        }//Actualizar

        /// <summary>
        /// Funcion que actualiza en la capa de persistencia un conjunto de bancos
        /// </summary>
        /// <param name="bancos">Conjunto de bancos a actualizar en la capa de persistencia</param>
        /// <returns>El indice del ultimo  banco el cual fue actualizado con exito a la capa de persistencia</returns>
        public int Actualizar(BancoDTO[] bancos)
        {
            log.Info("Inicio BancoDao.Actualizar(Banco[] bancos)");

            //Validacion de datos
            Validar(bancos, Validaciones.Nulo & Validaciones.IdentificadorNegativo);

            int i = 0;
            for (; i < bancos.Length; i++)
            {
                if (!Actualizar(bancos[i]))
                {
                    log.Error("No se pudo actualizar el banco con id : " + bancos[i].Id);
                    break;
                }
            }

            log.Info("Fin BancoDao.Actualizar(Banco[] bancos)");

            return i;
        }//Actualizar

        /// <summary>
        /// Funcion que determina si el objeto actualmente se encuentra registrado en la capa de persistencia
        /// </summary>
        /// <param name="banco">Objeto a validar su existencia</param>
        /// <returns>Verdadero en caso de que no exista ningun banco</returns>
        public bool Existe(BancoDTO banco)
        {
            log.Info("Inicio BancoDao.Existe(BancoDTO banco)");

            //Validacion de datos
            Validar(banco, Validaciones.Nulo);

            bool existe = this.Obtener(banco.Id) != null;
            log.Debug("Busqueda por id : " + existe);

            log.Info("Fin BancoDao.Existe(BancoDTO banco)");

            return existe;
        }//Existe

        /// <summary>
        /// Funcion que devuelve la cantidad de bancos registrados en la capa de persistencia
        /// </summary>
        /// <returns>Cantidad de bancos registrados</returns>
        public int ObtenerCantidad()
        {
            log.Info("Inicio BancoDao.ObtenerCantidad()");

            Accion accion = admin.ObtenerAccion(CatalogoAcciones.Banco.OBTENER_CANTIDAD);
            log.Debug("Accion : " + accion);
            admin.Ejecutar(accion);

            log.Info("Fin BancoDao.ObtenerCantidad()");

            return (int)accion.Parametros[Accion.OUTPUT];
        }//ObtenerCantidad

        /// <summary>
        /// Funcion que resetea el identificador del catalogo de bancos al menor registrado en la tabla
        /// </summary>
        public void ResetearId()
        {
            log.Info("Inicio BancoDao.ResetearId()");

            Accion accion = admin.ObtenerAccion(CatalogoAcciones.Banco.RESETEAR_ID);
            log.Debug("Accion : " + accion);
            admin.Ejecutar(accion);

            log.Info("Fin BancoDao.ResetearId()");
        }//ResetearId

        /// <summary>
        /// Funcion que valida los campos correctos del objeto
        /// </summary>
        /// <param name="banco">Objeto a ser validado</param>
        /// <param name="validacion">Opciones de validacion de los campos</param>
        public void Validar(BancoDTO banco, Validaciones validacion)
        {
            log.Info("Inicio BancoDao.Validar(BancoDTO banco, Validaciones validacion)");

            if ((validacion & Validaciones.Nulo) == Validaciones.Nulo)
            {
                log.Debug("Validacion de objeto nulo");
                if (banco == null)
                {
                    log.Error("El objeto es nulo");
                    throw new DAOException("El objeto es nulo");
                }
            }

            if ((validacion & Validaciones.DescripcionVacia) == Validaciones.DescripcionVacia)
            {
                log.Debug("Validacion de descripcion vacia");
                if (string.IsNullOrEmpty(banco.Descripcion))
                {
                    log.Error("El banco no tiene descripcion alguna");
                    throw new DAOException("El banco no tiene descripcion alguna");
                }
            }

            if ((validacion & Validaciones.IdentificadorNegativo) == Validaciones.IdentificadorNegativo)
            {
                log.Debug("Validacion de identificador negativo");
                if (banco.Id < 0)
                {
                    log.Error("El banco no puede tener un identificador negativo");
                    throw new DAOException("El banco no puede tener un identificador negativo");
                }
            }

            log.Info("Fin BancoDao.Validar(BancoDTO banco, Validaciones validacion)");
        }//Validar

        /// <summary>
        /// Funcion que valida cada uno de los elementos de un conjunto de bancos
        /// </summary>
        /// <param name="bancos">Conjunto de bancos a ser validados</param>
        /// <param name="validacion">Opcion de validacion de campos</param>
        public void Validar(BancoDTO[] bancos, Validaciones validacion)
        {
            log.Info("Inicio BancoDao.Validar(BancoDTO[] bancos, Validaciones validacion)");

            if (bancos == null)
            {
                log.Error("El objeto es nulo");
                throw new DAOException("El objeto es nulo");
            }

            foreach (BancoDTO b in bancos)
            {
                Validar(b, validacion);
            }

            log.Info("Fin BancoDao.Validar(BancoDTO[] bancos, Validaciones validacion)");
        }//Validar

        #endregion

        #region ICatalogo

        /// <summary>
        /// Funcion que obtiene todos los bancos que concidan con la descripcion solicitada
        /// </summary>
        /// <param name="descripcion">Descripcion a buscar en la capa de persistencia</param>
        /// <returns>Conjunto de objetos que comparten la misma descripcion</returns>
        public BancoDTO[] ObtenerPorDescripcion(string descripcion)
        {
            log.Info("Inicio BancoDao.ObtenerPorDescripcion(string descripcion)");

            BancoDTO[] resultado = null;
            Accion accion = admin.ObtenerAccion(CatalogoAcciones.Banco.OBTENER_POR_DESCRIPCION);
            log.Debug("Accion : " + accion);
            accion.Parametros[Accion.INPUT] = descripcion;
            admin.Ejecutar(accion);
            resultado = accion.Parametros[Accion.OUTPUT] as BancoDTO[];

            if (resultado != null && resultado.Length == 0)
            {
                log.Warn("Reseteando el valor obtenido");
                resultado = null;
            }

            log.Info("Fin BancoDao.ObtenerPorDescripcion(string descripcion)");

            return resultado;
        }//ObtenerPorDescripcion

        /// <summary>
        /// Funcion que obtiene todos los bancos que tengan en su descripcion el parametro solicitado
        /// </summary>
        /// <param name="descripcion">Descripcion a contener en las descripciones de los objetos</param>
        /// <returns>Conjunto de objetos que incluyen en su descripcion en parametro deseado</returns>
        public BancoDTO[] ObtenerPorDescripcionSimilar(string descripcion)
        {
            log.Info("Inicio BancoDao.ObtenerPorDescripcionSimilar(string descripcion)");

            BancoDTO[] resultado = null;
            Accion accion = admin.ObtenerAccion(CatalogoAcciones.Banco.OBTENER_POR_DESCRIPCION_SIMILAR);
            accion.Parametros[Accion.INPUT] = descripcion;
            log.Debug("Accion : " + accion);
            admin.Ejecutar(accion);
            resultado = accion.Parametros[Accion.OUTPUT] as BancoDTO[];

            if (resultado != null && resultado.Length == 0)
            {
                log.Warn("Reseteando el valor obtenido");
                resultado = null;
            }

            log.Info("Fin BancoDao.ObtenerPorDescripcionSimilar(string descripcion)");

            return resultado;
        }//ObtenerPorDescripcionSimilar

        #endregion

        #region IActivo

        /// <summary>
        /// Funcion que devuelve todos los objetos con estatus de activo de la capa de persistencia
        /// </summary>
        /// <returns>Conjunto de objetos con el mismo estatus de activo</returns>
        public BancoDTO[] ObtenerActivos()
        {
            log.Info("Inicio BancoDao.ObtenerActivos()");

            BancoDTO[] resultado = null;
            Accion accion = admin.ObtenerAccion(CatalogoAcciones.Banco.OBTENER_ACTIVOS);
            log.Debug("Accion : " + accion);
            admin.Ejecutar(accion);
            resultado = accion.Parametros[Accion.OUTPUT] as BancoDTO[];

            if (resultado != null && resultado.Length == 0)
            {
                log.Warn("Reseteando el valor obtenido");
                resultado = null;
            }

            log.Info("Fin BancoDao.ObtenerActivos()");

            return resultado;
        }//ObtenerActivos

        /// <summary>
        /// Funcion que devuelve todos los objetos con estatus de inactivo de la capa de persistencia
        /// </summary>
        /// <returns>Conjunto de objetos con el mismo estatus de inactivo</returns>
        public BancoDTO[] ObtenerInactivos()
        {
            log.Info("Inicio BancoDao.ObtenerInactivos()");

            BancoDTO[] resultado = null;
            Accion accion = admin.ObtenerAccion(CatalogoAcciones.Banco.OBTENER_INACTIVOS);
            log.Debug("Accion : " + accion);
            admin.Ejecutar(accion);
            resultado = accion.Parametros[Accion.OUTPUT] as BancoDTO[];

            if (resultado != null && resultado.Length == 0)
            {
                log.Warn("Reseteando el valor obtenido");
                resultado = null;
            }

            log.Info("Fin BancoDao.ObtenerInactivos()");

            return resultado;
        }//ObtenerInactivos

        /// <summary>
        /// Funcion que actualiza el estatus a activo del banco en la capa de persistencia
        /// </summary>
        /// <param name="bancoInactivo">Objeto con el estatus a actualizar</param>
        /// <returns>Verdadero en caso de exito falso en caso contrario</returns>
        public bool Activar(BancoDTO bancoInactivo)
        {
            log.Info("Inicio BancoDao.Activar(BancoDTO bancoInactivo)");

            if (!Existe(bancoInactivo))
            {
                log.Error("No existe el banco a activar");
                throw new DAOException("No existe el banco a activar");
            }

            Accion accion = admin.ObtenerAccion(CatalogoAcciones.Banco.ACTIVAR);
            log.Debug("Accion : " + accion);
            bool respuesta = false;
            accion.Parametros[Accion.INPUT] = bancoInactivo;

            admin.Ejecutar(accion);
            respuesta = (bool)accion.Parametros[Accion.OUTPUT];
            bancoInactivo.Activo = respuesta ? true : bancoInactivo.Activo;

            log.Info("Fin BancoDao.Activar(BancoDTO bancoInactivo)");

            return respuesta;
        }//Activar

        /// <summary>
        /// Funcion que actualiza el estatus a desactivo del banco en la capa de persistencia
        /// </summary>
        /// <param name="bancoActivo">Objeto con el estatus a actualizar</param>
        /// <returns>Verdadero en caso de exito falso en caso contrario</returns>
        public bool Desactivar(BancoDTO bancoActivo)
        {
            log.Info("Inicio BancoDao.Desactivar(BancoDTO bancoActivo)");

            if (!Existe(bancoActivo))
            {
                log.Error("No existe el banco a desactivar");
                throw new DAOException("No existe el banco a desactivar");
            }

            Accion accion = admin.ObtenerAccion(CatalogoAcciones.Banco.DESACTIVAR);
            log.Debug("Accion : " + accion);
            bool respuesta = false;
            accion.Parametros[Accion.INPUT] = bancoActivo;

            admin.Ejecutar(accion);
            respuesta = (bool)accion.Parametros[Accion.OUTPUT];
            bancoActivo.Activo = respuesta ? false : bancoActivo.Activo;

            log.Info("Fin BancoDao.Desactivar(BancoDTO bancoActivo)");

            return respuesta;
        }//Desactivar

        #endregion
    }//BancoDao
}//Electrocucaracha.AdminPersonal.DAO